Media

WordPressからEmDashに移行して、PageSpeed Insightsはスマホ99点・PC100点に。速さの理由と、移行直後の48点から上げた6つの改善【コード付き】

WordPressからEmDashに移行して、PageSpeed Insightsはスマホ99点・PC100点に。速さの理由と、移行直後の48点から上げた6つの改善【コード付き】

当社のホームページは、2026年10月に WordPress から EmDash(Astro をもとにした CMS)へ移行しました。移行の経緯は「WordPress から Astro ベースの CMS に移行して、通信量を 3 分の 1 にした話」に、EmDash そのものの特徴は「EmDash と WordPress の比較」にまとめています。

今回は、その結果を Google の PageSpeed Insights で測った記録です。結果から言うと、スマートフォン 99 点、デスクトップ 100 点でした。

ただし、最初からこの点数だったわけではありません。移行した直後は、スマートフォンで 48 点でした。CMS を変えただけでは速くならない部分があり、原因を一つずつ調べて直しています。

この記事では、

  • PageSpeed Insights の実際の計測画面(スマートフォン・デスクトップ)
  • EmDash(Astro)でなぜ速くできるのか
  • 移行直後の 48 点から 99 点にした 6 つの改善(コード付き)
  • 計測するときの注意点

を、制作会社の目線で紹介します。

計測日は 2026年11月8日、対象はトップページ(https://esolab.co.jp/)です。PageSpeed Insights の点数は、計測のたびに数点ほど変わります。

結果: スマートフォン 99 点・デスクトップ 100 点

PageSpeed Insights の結果のまとめ。スマートフォン 99 点・デスクトップ 100 点、4 つのカテゴリーすべてで 90 点以上

カテゴリー

スマートフォン

デスクトップ

パフォーマンス

99

100

ユーザー補助(アクセシビリティ)

100

100

おすすめの方法

100

100

SEO

100

100

パフォーマンスの点数のもとになっている指標は次のとおりです。

指標

意味

スマートフォン

デスクトップ

FCP(First Contentful Paint)

最初に何かが表示されるまで

1.2 秒

0.3 秒

LCP(Largest Contentful Paint)

一番大きな要素が表示されるまで

1.7 秒

0.4 秒

TBT(Total Blocking Time)

操作できない時間の合計

100 ミリ秒

70 ミリ秒

CLS(Cumulative Layout Shift)

表示中のレイアウトのずれ

0.006

0.005

Speed Index

画面が埋まっていく速さ

2.6 秒

0.9 秒

スマートフォンの計測は、PageSpeed Insights が「Moto G Power」相当の端末と低速 4G 回線を想定して行うものです。実際の新しいスマートフォンと速い回線では、もっと速く表示されます。

スマートフォンの計測画面

PageSpeed Insights のスマートフォンの結果。パフォーマンス 99、ユーザー補助 100、おすすめの方法 100、SEO 100。FCP 1.2 秒、LCP 1.7 秒、TBT 100 ミリ秒、CLS 0.006、Speed Index 2.6 秒
PageSpeed Insights(スマートフォン)。2026年11月8日 14:28 に計測

デスクトップの計測画面

PageSpeed Insights のデスクトップの結果。4 つのカテゴリーすべて 100。FCP 0.3 秒、LCP 0.4 秒、TBT 70 ミリ秒、CLS 0.005、Speed Index 0.9 秒
PageSpeed Insights(デスクトップ)。2026年11月8日 14:28 に計測

実際の利用者のデータ(Core Web Vitals)も「合格」

PageSpeed Insights の上の段には、Chrome を使う実際の利用者から集めたデータ(フィールドデータ)が表示されます。デスクトップでは、サイト全体(オリジン)で Core Web Vitals の評価が「合格」(LCP 1.6 秒・CLS 0・TTFB 0.4 秒)でした。

PageSpeed Insights のフィールドデータ(デスクトップ・オリジン)。ウェブに関する主な指標の評価は合格。LCP 1.6 秒、CLS 0、FCP 1 秒、TTFB 0.4 秒
実際の利用者のデータ(過去 28 日間・デスクトップ・サイト全体)

フィールドデータは過去 28 日間の集計で、移行前の WordPress の期間も一部含まれています。スマートフォンは、まだデータが足りず表示されませんでした。

WordPress の頃との違い

旧サイト(WordPress)は、同じ条件で PageSpeed Insights の点数を記録していなかったため、点数を並べて比べることはできません。代わりに、移行のときに同じ条件で測った通信量などの比較を載せます(トップページ・スマートフォン相当)。

項目

WordPress(移行前)

EmDash(移行後)

読み込むファイル数

58

12

通信量

約 4.9MB

約 1.7MB

読み込み完了までの時間

約 8.5 秒

約 3.1 秒

外部のスクリプト

5

0(計測タグは後から読み込み)

今のトップページで、当社のサーバーから読み込む JavaScript は5 ファイル・合計約 10KB(圧縮後)だけです。通信量の大部分は、メインビジュアルの短い動画(ページの読み込みが終わってから読み込みます)が占めています。

EmDash(Astro)で速くできる理由

EmDash は Astro という仕組みの上に作られた CMS です。Astro は「HTML を先に届けて、JavaScript は必要な部分にだけ使う」という考え方で作られています。

1. ページはサーバーで HTML にしてから届ける

WordPress も PHP で HTML を作りますが、テーマやプラグインが増えるほど、CSS と JavaScript のファイルが積み重なります。Astro では、ページの部品(コンポーネント)はサーバー側で HTML に変換され、ブラウザには JavaScript を送らないのが基本です。

Astro のコンポーネントの例astro
---
// --- の間はサーバーで実行される。このコードはブラウザには送られない
const { label, url } = Astro.props;
const href = url.startsWith("/") ? url : "/contact/";
---

<!-- ブラウザに届くのは、できあがった HTML だけ -->
<a class="button" href={href}>{label}</a>

2. 動きが必要な部分だけ JavaScript を使う

チャットボットやメニューの開閉など、動きが必要な部分だけに <script> を書きます。Astro がビルドのときにまとめて圧縮し、そのページで使う分だけを読み込みます。当社のトップページで使っている JavaScript は、チャットボット(約 4KB)、フォームの文言、表のスクロールの案内などで、合計約 10KB です。

3. ビルドしたファイルは 1 年キャッシュ

Astro がビルドした CSS・JavaScript は、ファイル名に内容のハッシュ(例: Base.A8CkvuEI.css)が付きます。内容が変わればファイル名も変わるので、ブラウザに1 年間キャッシュさせても古い表示が残りません。サーバー(nginx)の設定は次のとおりです。

deploy/server/nginx.sh(抜粋)nginx
location /_astro/ {
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable";
}

4. データベースはファイル 1 つ(SQLite)

EmDash は SQLite(ファイル 1 つのデータベース)で動かしています。サーバーから最初の 1 バイトが届くまでの時間(TTFB)は、実際の利用者のデータで 0.4 秒でした。

移行直後は 48 点だった。99 点にした 6 つの改善

移行した直後、拡張機能のない Chrome でトップページを測ると、スマートフォンのパフォーマンスは 48 点(LCP 6.0 秒・TBT 1.7 秒)でした。CMS を変えても、デザインの演出や動画、計測タグの読み込み方は、別に見直す必要があります。

移行直後と改善後の比較。スマートフォンのパフォーマンス 48 点から 99 点、LCP 6.0 秒から 1.7 秒、TBT 1,730 ミリ秒から 100 ミリ秒

改善 1: 一番大きな画像を、フェードの演出なしで最初から表示する

Lighthouse の「LCP の内訳」を見ると、画像の読み込みは 0.2 秒ほどで終わっているのに、表示されるまでの待ち(要素のレンダリングの遅延)が 2〜4 秒ありました。原因は、トップの動画の枠を、ページを開いてからふわっと表示する演出でした。

LCP の対象は、トップの小さな動画の枠でした。そこで、動画の静止画を poster 属性ではなく <img> にし、表示サイズに合わせた WebP を srcset で出し分け、fetchpriority="high" で優先して読み込むようにしました。枠のフェードの演出も外しています。

src/components/blocks/MainVisual.astro(抜粋)astro
<img
  class="mv__poster"
  src="/movie/mv-picture-640.webp"
  srcset="/movie/mv-picture-320.webp 320w, /movie/mv-picture-640.webp 640w"
  sizes="(max-width: 760px) 58vw, clamp(200px, 20vw, 340px)"
  width="640"
  height="360"
  alt=""
  fetchpriority="high"
  decoding="async"
/>
<video src="/movie/clips/..." muted playsinline preload="none"></video>

動画は、再生が始まってから静止画の上に重ねて表示します。

css
/* 再生が始まるまでは動画を隠し、下の静止画(<img>)を見せる */
.mv__stack video:not([data-mv-playing]) {
  opacity: 0;
}

改善 2: ページ全体のフェードは「不透明度 0」から始めない

当社のサイトは、ページを開いたときに本文がふわっと現れる演出を入れています。ところが、ブラウザは不透明度が 0 の間に描いた画像や文字を、LCP の対象にしません。その結果、画像を出したのに、LCP が「表示されていない」と判定されていました。

見た目は変えずに、始まりの不透明度を 0.01 にしました。

src/styles/motion.csscss
@keyframes page-in {
  from {
    opacity: 0.01; /* 0 にすると、その間に描いたものが LCP の対象にならない */
    transform: translate3d(0, 24px, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

この 2 つの改善で、LCP の対象は静止画になり、表示までの待ちは 0.1 秒ほどになりました。

改善 3: 計測タグ(GA4・Clarity)はページの読み込みが終わってから

Google アナリティクス(GA4)と Microsoft Clarity のスクリプトは、ページと同時に読み込むと、表示中のメインスレッドを使ってしまいます。そこで、呼び出し口(`gtag()`・`clarity()`)だけ先に用意し、外部のスクリプトはページの読み込みが終わってブラウザの手が空いてから読み込むようにしました。先に送ったページビューなどは、読み込み後にまとめて送られます。

src/lib/seo/tracking.ts が出力するスクリプト(読みやすく整形)js
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag("js", new Date());
gtag("config", "G-XXXXXXXXXX");

(function (w, d, sources) {
  function load() {
    sources.forEach(function (src) {
      var s = d.createElement("script");
      s.async = true;
      s.src = src;
      d.head.appendChild(s);
    });
  }
  function idle() {
    (w.requestIdleCallback || function (f) { setTimeout(f, 1); })(load, { timeout: 3000 });
  }
  if (d.readyState === "complete") idle();
  else w.addEventListener("load", idle, { once: true });
})(window, document, ["https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"]);

TBT(操作できない時間の合計)は 1,730 ミリ秒から 100 ミリ秒前後になりました。

改善 4: 動画は表示サイズに合わせて書き出し直す

トップの小さな動画の枠は、大きくても幅 340px です。ところが、動画は 960×540 で書き出していました。640×360 に書き出し直し、29 本の合計を 8.0MB から 3.7MB にしました。

bash
ffmpeg -i clip.mp4 -an \
  -vf "scale=640:-2:flags=lanczos,fps=24" \
  -c:v libx264 -preset slow -crf 28 -profile:v main -pix_fmt yuv420p \
  -movflags +faststart clip-640.mp4

-movflags +faststart は、動画の情報をファイルの先頭に置き、読み込みながら再生を始められるようにする指定です。

改善 5: JavaScript も gzip で圧縮する

Lighthouse の「テキスト圧縮の有効化」の指摘を調べると、CSS は圧縮されているのに、JavaScript だけ圧縮されていませんでした。Astro(Node.js)は JavaScript を text/javascript という種類で返しますが、nginx の設定には application/javascript しか書いていなかったためです。

deploy/server/nginx.sh(抜粋)nginx
gzip on;
# Astro(Node)は .js を text/javascript で返すため、両方の書き方を入れる
gzip_types text/css text/javascript application/javascript application/json image/svg+xml application/xml application/rss+xml text/plain;

チャットボットのスクリプトは 8.5KB から約 4KB になりました。

改善 6: 読み込み中にレイアウトの計算を強制しない(強制リフロー)

ヘッダーの高さを測るために getBoundingClientRect() を呼んでいたところ、ページの読み込み中にレイアウトの計算を強制していました(Lighthouse の「強制リフロー」)。高さは CSS 変数で決めているので、そちらを読むように変えました。

src/components/SiteHeader.astro(抜粋)ts
// 変更前: レイアウトの計算を強制する
// const height = header.getBoundingClientRect().height || 80;

// 変更後: CSS 変数(--header-height)を読むだけ
const height =
  parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--header-height")) || 80;
自社サイトの表示速度を相談する

PageSpeed Insights の結果(URL や画面)を添えていただければ、原因と改善の優先順位をお伝えします(無料)

計測するときの注意点

PageSpeed Insights や Lighthouse の点数は、測り方で大きく変わります。今回の作業中にも、次のようなことがありました。

  • ブラウザの拡張機能が結果に入る: Chrome の開発者ツールで Lighthouse を実行すると、広告ブロッカーなどの拡張機能の JavaScript も「使っていない JavaScript」として数えられます。シークレットウィンドウか PageSpeed Insights で測りましょう
  • CMS にログインしたまま測らない: 管理画面にログインしていると、編集用のツールバーが表示されたり、キャッシュの設定が変わったりします
  • 点数は毎回少し変わる: 同じページでも数点は上下します。1 回の結果ではなく、何度か測って傾向を見ます
  • ラボデータとフィールドデータは別物: 点数(ラボデータ)は決まった条件での模擬計測、Core Web Vitals の評価(フィールドデータ)は実際の利用者の 28 日間の集計です。検索の評価に使われるのはフィールドデータのほうです

残っている指摘

点数は 99〜100 点ですが、指摘がゼロになったわけではありません。

  • レンダリングをブロックしているリクエスト: CSS(3 ファイル)の読み込みです。HTML に埋め込むとページを移るたびに読み直しになるため、キャッシュを優先して今のままにしています
  • 使用していない JavaScript: ほとんどが Google アナリティクスのスクリプトです。読み込みは後回しにしていますが、使うのをやめない限り残ります
  • サードパーティ Cookie: Microsoft Clarity の Cookie です(Lighthouse の「おすすめの方法」で指摘されることがあります)。行動の分析に使っているため、残しています

点数を 100 点にすること自体を目的にせず、お客様が感じる速さと、分析やデザインの価値のバランスで判断しています。

よくある質問

WordPress のままでも、PageSpeed Insights の点数は上げられますか?

上げられます。画像の大きさと形式、使っていないプラグインや CSS・JavaScript の整理、キャッシュの設定、計測タグの読み込み方などで、大きく改善することがあります。今回の 6 つの改善のうち、多くは WordPress でも同じ考え方で使えます。

点数が低いと、検索順位は下がりますか?

Google は、実際の利用者のデータ(Core Web Vitals)を検索の評価の要素の一つにしています。影響は内容の良さほど大きくはないとされていますが、表示が遅いと、検索から来た人がすぐに戻ってしまう原因になります。

EmDash に移行すれば、必ず速くなりますか?

速くしやすい仕組みですが、必ず速くなるわけではありません。当社のサイトも、移行直後はスマートフォンで 48 点でした。動画や演出、計測タグなど、サイトごとの作り方で結果は変わります。

自社のサイトの表示速度だけ見てもらうことはできますか?

できます。今のサイトの URL を教えていただければ、PageSpeed Insights の結果をもとに、原因と改善の優先順位をお伝えします。当社が制作していないサイトでも対応します。

まとめ

  • WordPress から EmDash(Astro)に移行し、PageSpeed Insights はスマートフォン 99 点・デスクトップ 100 点、ほかの 3 カテゴリーもすべて 100 点でした
  • 実際の利用者のデータ(デスクトップ・サイト全体)でも、Core Web Vitals は合格です
  • 速さの土台は、HTML を先に届けて、JavaScript を必要な部分だけに絞る仕組みと、長くキャッシュできるファイルの配信です
  • それでも移行直後は 48 点でした。LCP と演出の関係、動画の大きさ、計測タグの読み込み方、圧縮の設定、強制リフローを直して 99 点にしています
  • 点数は測り方で変わります。拡張機能やログインのない状態で、何度か測って判断しましょう

「自社のサイトが遅い気がする」「PageSpeed Insights の点数が低いけれど、どこから直せばいいか分からない」という方は、お気軽にご相談ください。

表示速度の改善を無料で相談する

フォームは 24 時間受付。ご相談内容は入力済みなので、お名前とご連絡先を入れるだけで送れます

※ PageSpeed Insights、Lighthouse、Google アナリティクスは Google LLC の商標です。Microsoft Clarity は Microsoft Corporation の商標です。

Contact

まずはお気軽にご相談ください。

WEB制作・システム開発・動画制作など、お問い合わせはこちらから承っております。

制作のご依頼・ご相談その他のお問い合わせ
メディア一覧へ戻る
お問い合わせ